package com.aplink.generic.widgets;

import java.lang.ref.WeakReference;
import java.util.List;

import sdt.brc.android.BarcodeReaderResult;
import sdt.brc.android.BarcodeReaderUtil;
import sdt.brc.android.BarcodeScanDialog;
import sdt.brc.android.OnRecognitionListener;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.YuvImage;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.BundleConstant;
import com.aplink.generic.constant.HandlerConstant;
import com.aplink.generic.dictionary.GenericDictionary;
import com.aplink.generic.interfaces.OnGetObjProInfo;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.controlspec.BarcodeSpec;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.util.ResourcesHelper;

public class ApLinkBarcodeScanner extends ApLinkBaseView implements
        OnRecognitionListener {
    private class LoadBarcodeScanner extends AsyncTask<Void, Void, Void> {
        private final WeakReference<Activity> mActivity;
        private ProgressDialog mProgressDialog;

        public LoadBarcodeScanner(final Activity activity) {
            this.mActivity = new WeakReference<Activity>(activity);
        }

        @Override
        protected Void doInBackground(final Void... params) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ApLinkBarcodeScanner.this.mCamDlg.show();
                }
            });

            return null;
        }

        @Override
        protected void onPostExecute(final Void result) {
            super.onPostExecute(result);
            this.mProgressDialog.hide();
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            this.mProgressDialog = new ProgressDialog(this.mActivity.get());
            this.mProgressDialog.setCanceledOnTouchOutside(false);
            this.mProgressDialog.show();
        }
    }

    /**
     * 
     */
    private static final long serialVersionUID = -1226967998853204573L;

    private Bitmap mBarcodeImage = null;
    private BarcodeSpec mBarcodeSpec = null;
    private String mBarcodeValue = null;
    private View mBarcodeView = null;
    private BarcodeScanDialog mCamDlg = null;
    private final View.OnClickListener mClickListener = new View.OnClickListener() {

        @Override
        public void onClick(final View v) {
            new LoadBarcodeScanner(ApLinkBarcodeScanner.this.getActivity())
                    .execute();
        }
    };
    private View mCtrlImageDispllay = null;

    private View mCtrlResult = null;

    private final View mOverlayView = null;

    public ApLinkBarcodeScanner(final GenericFragment genericFragment,
            final ControlSpec controlSpec, final View view) {
        super(genericFragment, controlSpec, view);
        this.mBarcodeSpec = (BarcodeSpec) controlSpec;
        this.mBarcodeView = view;
    }

    @Override
    public void clear() {
        this.mBarcodeValue = null;
        this.mBarcodeImage = null;
    }

    public void closeScanBarcode() {
        if (this.mCamDlg != null) {
            this.mCamDlg.dismiss();
        }
    }

    @Override
    public GenericAttribute getAttribute() {
        return null;
    }

    public Bitmap getBarcodeImage() {
        return this.mBarcodeImage;
    }

    public String getBarcodeValue() {
        return this.mBarcodeValue;
    }

    public View getBarcodeView() {
        return this.mBarcodeView;
    }

    @Override
    public GenericDictionary<String, GenericAttribute> getListAttributes() {
        return null;
    }

    @Override
    public View getView() {
        return null;
    }

    public void hideCameraDialog() {
        if (this.mCamDlg != null) {
            this.mCamDlg.dismiss();
        }
    }

    @Override
    protected void initViewProperties() {
        if (this.mOverlayView == null) {
            this.mCamDlg = new BarcodeScanDialog(getActivity(),
                    "Purchased License key");
        } else {
            this.mCamDlg = new BarcodeScanDialog(getActivity(),
                    "Purchased License key");
        }
        if (this.mCamDlg != null) {
            this.mCamDlg.setBarcodeTypes(this.mBarcodeSpec.getBarcodeType());
            this.mCamDlg.enableFlashlight(this.mBarcodeSpec
                    .isEnableFlashLight());
            this.mCamDlg.setRecognitionListener(this);
            this.mCamDlg.showActiveArea(true);
        }

        final String ctrlResultId = this.mBarcodeSpec.getCtrlResult();
        int id = ResourcesHelper.getViewIdByName(ctrlResultId);
        this.mCtrlResult = getActivity().findViewById(id);
        id = ResourcesHelper.getViewIdByName(this.mBarcodeSpec.getImagePath());
        this.mCtrlImageDispllay = getActivity().findViewById(id);
    }

    @Override
    protected void loadBindingObject() {

    }

    @Override
    protected void loadDefaultObject() {

    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void onRecognitionResults(final List results, final YuvImage srcImage) {
        hideCameraDialog();
        for (final BarcodeReaderResult barcodeReaderResult : (List<BarcodeReaderResult>) results) {
            if (this.mCtrlResult instanceof TextView) {
                this.mBarcodeValue = barcodeReaderResult.getValue();
                ((TextView) this.mCtrlResult).setText(this.mBarcodeValue);
            }
        }
        if (srcImage != null) {
            this.mBarcodeImage = BarcodeReaderUtil
                    .decodeImageToBitmap(srcImage);
            if (this.mCtrlImageDispllay instanceof ImageView) {
                ((ImageView) this.mCtrlImageDispllay)
                        .setImageBitmap(this.mBarcodeImage);
            } else if (this.mCtrlImageDispllay instanceof TextView) {
                final Drawable top = new BitmapDrawable(getResources(),
                        this.mBarcodeImage);
                ((TextView) this.mCtrlImageDispllay)
                        .setCompoundDrawablesWithIntrinsicBounds(null, top,
                                null, null);
            }
        }

        if (getGenericFragment().getGenericHandler() != null) {
            final Message message = new Message();
            if ((this.mBarcodeSpec.getValue() != null)
                    && !this.mBarcodeSpec.getValue().isEmpty()) {
                final int taskType = Integer.parseInt(this.mBarcodeSpec
                        .getValue());
                message.what = taskType;
            } else {
                message.what = HandlerConstant.BARCODE_DETECTED;
            }
            final Bundle bundle = new Bundle();
            bundle.putString(BundleConstant.BARCODE_RESULT, this.mBarcodeValue);
            bundle.putParcelable(BundleConstant.BARCODE_BITMAP,
                    this.mBarcodeImage);
            message.setData(bundle);
            getGenericFragment().getGenericHandler().sendMessage(message);
        }
    }

    public void setBarcodeView(final View barcodeView) {
        this.mBarcodeView = barcodeView;
    }

    @Override
    protected void setEventListener() {
        this.mBarcodeView.setOnClickListener(this.mClickListener);
    }

    @Override
    public void setObjPropInfoTemp(final OnGetObjProInfo getObjProInfo) {
        throw new UnsupportedOperationException(this.getClass().getSimpleName()
                + " is not support this method");
    }

    @Override
    public void setOnClickListener(final OnClickListener onClickListener) {
        throw new UnsupportedOperationException(this.getClass().getSimpleName()
                + " is not support this method");
    }

}
